#include <linux/module.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/platform_device.h>

#include "led_opr.h"
#include "leddrv.h"
#include "led_resource.h"

static int g_ledpins[100]; // 存储次设备号
static int g_ledcnt = 0;   // 存储设备的个数

/*定义struct led_operations结构体需要的函数*/
static int board_demo_led_init(int which)
{
    printk("init gpio: group %d, pin %d\n", GROUP(g_ledpins[which]), PIN(g_ledpins[which]));
    switch (GROUP(g_ledpins[which]))
    {
    case 0:
    {
        printk("init pin of group 0 ...\n");
        break;
    }
    case 1:
    {
        printk("init pin of group 1 ...\n");
        break;
    }
    case 2:
    {
        printk("init pin of group 2 ...\n");
        break;
    }
    case 3:
    {
        printk("init pin of group 3 ...\n");
        break;
    }
    }

    return 0;
}

static int board_demo_led_ctl(int which, char status)
{
    printk("set led %s: group %d, pin %d\n", status ? "on" : "off", GROUP(g_ledpins[which]), PIN(g_ledpins[which]));

    switch (GROUP(g_ledpins[which]))
    {
    case 0:
    {
        printk("set pin of group 0 ...\n");
        break;
    }
    case 1:
    {
        printk("set pin of group 1 ...\n");
        break;
    }
    case 2:
    {
        printk("set pin of group 2 ...\n");
        break;
    }
    case 3:
    {
        printk("set pin of group 3 ...\n");
        break;
    }
    }

    return 0;
}
// led操作结构体，我们自己定义的
static struct led_operations board_demo_led_opr = {
    .init = board_demo_led_init,
    .ctl = board_demo_led_ctl,
};

// 获取led操作结构体
struct led_operations *get_board_led_opr(void)
{
    return &board_demo_led_opr;
}

/*定义platform_driver结构体需要的函数*/
// 定义probe函数
static int chip_demo_gpio_probe(struct platform_device *pdev)
{
    struct resource *res;
    int i = 0;

    while (1)
    {
        // 循环获取指定类型的资源
        res = platform_get_resource(pdev, IORESOURCE_IRQ, i++);
        if (!res) // 没有就退出
            break;

        g_ledpins[g_ledcnt] = res->start;  // 存储次设备号
        led_class_create_device(g_ledcnt); // 根据次设备号，创建设备节点。调用我们封装的函数。
        g_ledcnt++;
    }
    return 0;
}

static int chip_demo_gpio_remove(struct platform_device *pdev)
{
    struct resource *res;
    int i = 0;

    while (1)
    {
        res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
        if (!res)
            break;
        led_class_destroy_device(i); // 根据测设备号销毁设备节点，调用我们封装的函数。
        i++;
        g_ledcnt--;
    }
    return 0;
}

// 定义platform_driver结构体
static struct platform_driver chip_demo_gpio_driver = {
    .probe = chip_demo_gpio_probe,
    .remove = chip_demo_gpio_remove,
    .driver = {
        .name = "100ask_led",
    },
};

// 出口。入口。许可证
static int __init chip_demo_gpio_drv_init(void)
{
    int err;

    err = platform_driver_register(&chip_demo_gpio_driver);
    register_led_operations(&board_demo_led_opr); // 这是我们写的函数

    return 0;
}

static void __exit lchip_demo_gpio_drv_exit(void)
{
    platform_driver_unregister(&chip_demo_gpio_driver);
}

module_init(chip_demo_gpio_drv_init);
module_exit(lchip_demo_gpio_drv_exit);

MODULE_LICENSE("GPL");
